#pragma once

#include "Common.hpp"
// 网络地址和主机地址之间进行转换的类

class InetAddr
{
public:
    InetAddr(){}//无参构造函数
    // 我们在创建这个对象的时候他会自动将我们的网络地址结构体中的ip和端口转换为对应的形式
    // 网络转主机地址
    InetAddr(struct sockaddr_in &addr)//网络序列转主机
        : _addr(addr)
    {
        // 客户端的信息是保存在peer中的，我们可以打印出来看看
        _port = ntohs(_addr.sin_port); // 从网络中拿到的客户端的端口，属于网络序列，我们需要转换为主机系列
        //_ip = inet_ntoa(_addr.sin_addr); // 4字节的网络风格的ip地址，我们要转换为点分十进制字符串风格的形式
        char ipbuffer[64];
        inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(_addr));
        //_addr.sin_addr这个是我们传进来的四字节ip

        _ip = ipbuffer; // 将我们的ipbuffer 的地址赋值给 _ip，让 _ip 也指向转换后的字符串 IP
    }
    //完整的IP端口转成地址
    InetAddr(const std::string &ip, uint16_t port) // 主机转网络地址
        : _port(port), _ip(ip)
    {
        memset(&_addr, 0, sizeof(_addr)); // 先将_addr清零
        _addr.sin_family = AF_INET;       // 地址族为IPv4
        // AF_INET表示我们要做ip地址的转换
        inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr);
        /*
        AF_INET：表明要处理的是 IPv4 地址。
_ip.c_str()：借助 C++ 的 string 对象 _ip 得到其对应的 C 风格字符串。
&_addr.sin_addr：指向 sockaddr_in 结构体中的 sin_addr 字段，该字段用于存放二进制的 IPv4 地址。
        */
        _addr.sin_port = htons(_port); // 主机端口转换为网络端口
    }
    //只有端口号的
    InetAddr(uint16_t port) 
        : _port(port)
        , _ip("0")
    {
        memset(&_addr, 0, sizeof(_addr)); // 先将_addr清零
        _addr.sin_family = AF_INET;       // 地址族为IPv4
        _addr.sin_addr.s_addr = INADDR_ANY; // 绑定到任何地址上
        _addr.sin_port = htons(_port); // 主机端口转换为网络端口
    }

    uint16_t Port()
    {
        return _port;
    }
    std::string Ip()
    {
        return _ip;
    }
    const struct sockaddr_in &NetAddr() { return _addr; } // 将网络地址返回

    const struct sockaddr *NetAddrptr()//返回网络地址
    {
        return CONV(_addr);
    }

    socklen_t NetAddrlen()//返回网络地址结构体的长度
    {
        return sizeof(_addr);
    }
    bool operator==(const InetAddr &addr) // 判断两个元素是否相等
    {
        return addr._ip == _ip && addr._port == _port;
    }

    std::string StringAddr() // 将网络地址转换为字符串形式
    {
        return _ip + ":" + std::to_string(_port);
    }
    ~InetAddr()
    {
    }

private:
    struct sockaddr_in _addr; // 网络地址结构体
    std::string _ip;          // 网络地址
    uint16_t _port;           // 端口号
};